// Decompiled on 周六 2月 22 19:31:49 CST 2025 with Zomboid Decompiler v0.1.3 using Vineflower.
package zombie;

import java.util.ArrayList;
import java.util.Stack;
import zombie.Lua.LuaEventManager;
import zombie.characters.IsoPlayer;
import zombie.characters.IsoZombie;
import zombie.core.Core;
import zombie.core.math.PZMath;
import zombie.debug.DebugOptions;
import zombie.debug.LineDrawer;
import zombie.iso.IsoCell;
import zombie.iso.IsoChunk;
import zombie.iso.IsoChunkMap;
import zombie.iso.IsoGridSquare;
import zombie.iso.IsoUtils;
import zombie.iso.IsoWorld;
import zombie.network.GameClient;
import zombie.network.GameServer;
import zombie.network.ServerGUI;
import zombie.popman.MPDebugInfo;
import zombie.popman.ZombiePopulationManager;

public final class WorldSoundManager {
    public static final zombie.WorldSoundManager instance = new zombie.WorldSoundManager();
    public final ArrayList<zombie.WorldSoundManager.WorldSound> SoundList = new ArrayList();
    private final Stack<zombie.WorldSoundManager.WorldSound> freeSounds = new Stack();
    private static final zombie.WorldSoundManager.ResultBiggestSound resultBiggestSound = new zombie.WorldSoundManager.ResultBiggestSound();

    public void init(IsoCell cell) {
    }

    public void initFrame() {
    }

    public void KillCell() {
        this.freeSounds.addAll(this.SoundList);
        this.SoundList.clear();
    }

    public zombie.WorldSoundManager.WorldSound getNew() {
        return this.freeSounds.isEmpty() ? new zombie.WorldSoundManager.WorldSound() : (zombie.WorldSoundManager.WorldSound)this.freeSounds.pop();
    }

    public zombie.WorldSoundManager.WorldSound addSound(Object source, int x, int y, int z, int radius, int volume) {
        return this.addSound(source, x, y, z, radius, volume, false, 0.0F, 1.0F);
    }

    public zombie.WorldSoundManager.WorldSound addSound(Object source, int x, int y, int z, int radius, int volume, boolean stressHumans) {
        return this.addSound(source, x, y, z, radius, volume, stressHumans, 0.0F, 1.0F);
    }

    public zombie.WorldSoundManager.WorldSound addSound(
        Object source, int x, int y, int z, int radius, int volume, boolean stressHumans, float zombieIgnoreDist, float stressMod
    ) {
        return this.addSound(source, x, y, z, radius, volume, stressHumans, zombieIgnoreDist, stressMod, false, true, false);
    }

    public zombie.WorldSoundManager.WorldSound addSound(
        Object source,
        int x,
        int y,
        int z,
        int radius,
        int volume,
        boolean stressHumans,
        float zombieIgnoreDist,
        float stressMod,
        boolean sourceIsZombie,
        boolean doSend,
        boolean remote
    ) {
        if (radius <= 0) {
            return null;
        } else {
            zombie.WorldSoundManager.WorldSound worldSound;
            synchronized (this.SoundList) {
                worldSound = this.getNew().init(source, x, y, z, radius, volume, stressHumans, zombieIgnoreDist, stressMod);
                if (source == null) {
                    worldSound.sourceIsZombie = sourceIsZombie;
                }

                if (!GameServer.bServer) {
                    int int0 = zombie.SandboxOptions.instance.Lore.Hearing.getValue();
                    if (int0 == 4) {
                        int0 = 1;
                    }

                    int int1 = (int)PZMath.ceil((float)radius * this.getHearingMultiplier(int0));
                    int int2 = (x - int1) / 10;
                    int int3 = (y - int1) / 10;
                    int int4 = (int)Math.ceil((double)(((float)x + (float)int1) / 10.0F));
                    int int5 = (int)Math.ceil((double)(((float)y + (float)int1) / 10.0F));

                    for (int int6 = int2; int6 < int4; int6++) {
                        for (int int7 = int3; int7 < int5; int7++) {
                            IsoChunk isoChunk = IsoWorld.instance.CurrentCell.getChunk(int6, int7);
                            if (isoChunk != null) {
                                isoChunk.SoundList.add(worldSound);
                            }
                        }
                    }
                }

                this.SoundList.add(worldSound);
                ZombiePopulationManager.instance.addWorldSound(worldSound, doSend);
            }

            if (doSend) {
                if (GameClient.bClient) {
                    GameClient.instance.sendWorldSound(worldSound);
                } else if (GameServer.bServer) {
                    GameServer.sendWorldSound(worldSound, null);
                }
            }

            if (Core.bDebug && GameClient.bClient) {
                MPDebugInfo.AddDebugSound(worldSound);
            }

            return worldSound;
        }
    }

    public zombie.WorldSoundManager.WorldSound addSoundRepeating(Object source, int x, int y, int z, int radius, int volume, boolean StressHumans) {
        zombie.WorldSoundManager.WorldSound worldSound = this.addSound(source, x, y, z, radius, volume, StressHumans, 0.0F, 1.0F);
        if (worldSound != null) {
            worldSound.bRepeating = true;
        }

        return worldSound;
    }

    public zombie.WorldSoundManager.WorldSound getSoundZomb(IsoZombie zom) {
        IsoChunk isoChunk = null;
        if (zom.soundSourceTarget == null) {
            return null;
        } else if (zom.getCurrentSquare() == null) {
            return null;
        } else {
            isoChunk = zom.getCurrentSquare().chunk;
            ArrayList arrayList = null;
            if (isoChunk != null && !GameServer.bServer) {
                arrayList = isoChunk.SoundList;
            } else {
                arrayList = this.SoundList;
            }

            for (int _int = 0; _int < arrayList.size(); _int++) {
                zombie.WorldSoundManager.WorldSound worldSound = (zombie.WorldSoundManager.WorldSound)arrayList.get(_int);
                if (zom.soundSourceTarget == worldSound.source) {
                    return worldSound;
                }
            }

            return null;
        }
    }

    public zombie.WorldSoundManager.ResultBiggestSound getBiggestSoundZomb(int x, int y, int z, boolean ignoreBySameType, IsoZombie zom) {
        float float0 = -1000000.0F;
        zombie.WorldSoundManager.WorldSound worldSound0 = null;
        IsoChunk isoChunk = null;
        if (zom != null) {
            if (zom.getCurrentSquare() == null) {
                return resultBiggestSound.init(null, 0.0F);
            }

            isoChunk = zom.getCurrentSquare().chunk;
        }

        ArrayList arrayList = null;
        if (isoChunk != null && !GameServer.bServer) {
            arrayList = isoChunk.SoundList;
        } else {
            arrayList = this.SoundList;
        }

        for (int _int = 0; _int < arrayList.size(); _int++) {
            zombie.WorldSoundManager.WorldSound worldSound1 = (zombie.WorldSoundManager.WorldSound)arrayList.get(_int);
            if (worldSound1 != null && worldSound1.radius != 0) {
                float float1 = IsoUtils.DistanceToSquared((float)x, (float)y, (float)worldSound1.x, (float)worldSound1.y);
                float float2 = (float)worldSound1.radius * this.getHearingMultiplier(zom);
                if (!(float1 > float2 * float2)
                    && (!(float1 < worldSound1.zombieIgnoreDist * worldSound1.zombieIgnoreDist) || z != worldSound1.z)
                    && (!ignoreBySameType || !worldSound1.sourceIsZombie)) {
                    IsoGridSquare isoGridSquare0 = IsoWorld.instance.CurrentCell.getGridSquare(worldSound1.x, worldSound1.y, worldSound1.z);
                    IsoGridSquare isoGridSquare1 = IsoWorld.instance.CurrentCell.getGridSquare(x, y, z);
                    float float3 = float1 / (float2 * float2);
                    if (isoGridSquare0 != null && isoGridSquare1 != null && isoGridSquare0.getRoom() != isoGridSquare1.getRoom()) {
                        float3 *= 1.2F;
                        if (isoGridSquare1.getRoom() == null || isoGridSquare0.getRoom() == null) {
                            float3 *= 1.4F;
                        }
                    }

                    float3 = 1.0F - float3;
                    if (!(float3 <= 0.0F)) {
                        if (float3 > 1.0F) {
                            float3 = 1.0F;
                        }

                        float float4 = (float)worldSound1.volume * float3;
                        if (float4 > float0) {
                            float0 = float4;
                            worldSound0 = worldSound1;
                        }
                    }
                }
            }
        }

        return resultBiggestSound.init(worldSound0, float0);
    }

    public float getSoundAttract(zombie.WorldSoundManager.WorldSound sound, IsoZombie zom) {
        if (sound == null) {
            return 0.0F;
        } else if (sound.radius == 0) {
            return 0.0F;
        } else {
            float float0 = IsoUtils.DistanceToSquared(zom.x, zom.y, (float)sound.x, (float)sound.y);
            float float1 = (float)sound.radius * this.getHearingMultiplier(zom);
            if (float0 > float1 * float1) {
                return 0.0F;
            } else if (float0 < sound.zombieIgnoreDist * sound.zombieIgnoreDist && zom.z == (float)sound.z) {
                return 0.0F;
            } else if (sound.sourceIsZombie) {
                return 0.0F;
            } else {
                IsoGridSquare isoGridSquare0 = IsoWorld.instance.CurrentCell.getGridSquare(sound.x, sound.y, sound.z);
                IsoGridSquare isoGridSquare1 = IsoWorld.instance.CurrentCell.getGridSquare((double)zom.x, (double)zom.y, (double)zom.z);
                float float2 = float0 / (float1 * float1);
                if (isoGridSquare0 != null && isoGridSquare1 != null && isoGridSquare0.getRoom() != isoGridSquare1.getRoom()) {
                    float2 *= 1.2F;
                    if (isoGridSquare1.getRoom() == null || isoGridSquare0.getRoom() == null) {
                        float2 *= 1.4F;
                    }
                }

                float2 = 1.0F - float2;
                if (float2 <= 0.0F) {
                    return 0.0F;
                } else {
                    if (float2 > 1.0F) {
                        float2 = 1.0F;
                    }

                    return (float)sound.volume * float2;
                }
            }
        }
    }

    public float getStressFromSounds(int x, int y, int z) {
        float float0 = 0.0F;

        for (int _int = 0; _int < this.SoundList.size(); _int++) {
            zombie.WorldSoundManager.WorldSound worldSound = (zombie.WorldSoundManager.WorldSound)this.SoundList.get(_int);
            if (worldSound.stresshumans && worldSound.radius != 0) {
                float float1 = IsoUtils.DistanceManhatten((float)x, (float)y, (float)worldSound.x, (float)worldSound.y);
                float float2 = float1 / (float)worldSound.radius;
                float2 = 1.0F - float2;
                if (!(float2 <= 0.0F)) {
                    if (float2 > 1.0F) {
                        float2 = 1.0F;
                    }

                    float float3 = float2 * worldSound.stressMod;
                    float0 += float3;
                }
            }
        }

        return float0;
    }

    public void update() {
        if (!GameServer.bServer) {
            for (int int0 = 0; int0 < IsoPlayer.numPlayers; int0++) {
                IsoChunkMap isoChunkMap = IsoWorld.instance.CurrentCell.ChunkMap[int0];
                if (!isoChunkMap.ignore) {
                    for (int int1 = 0; int1 < IsoChunkMap.ChunkGridWidth; int1++) {
                        for (int int2 = 0; int2 < IsoChunkMap.ChunkGridWidth; int2++) {
                            IsoChunk isoChunk = isoChunkMap.getChunk(int2, int1);
                            if (isoChunk != null) {
                                isoChunk.updateSounds();
                            }
                        }
                    }
                }
            }
        }

        int int3 = this.SoundList.size();

        for (int int4 = 0; int4 < int3; int4++) {
            zombie.WorldSoundManager.WorldSound worldSound = (zombie.WorldSoundManager.WorldSound)this.SoundList.get(int4);
            if (worldSound != null && worldSound.life > 0) {
                worldSound.life--;
            } else {
                this.SoundList.remove(int4);
                this.freeSounds.push(worldSound);
                int4--;
                int3--;
            }
        }
    }

    public void render() {
        if (Core.bDebug && DebugOptions.instance.WorldSoundRender.getValue()) {
            if (!GameClient.bClient) {
                if (!GameServer.bServer || ServerGUI.isCreated()) {
                    int int0 = zombie.SandboxOptions.instance.Lore.Hearing.getValue();
                    if (int0 == 4) {
                        int0 = 2;
                    }

                    float float0 = this.getHearingMultiplier(int0);

                    for (int int1 = 0; int1 < this.SoundList.size(); int1++) {
                        zombie.WorldSoundManager.WorldSound worldSound0 = (zombie.WorldSoundManager.WorldSound)this.SoundList.get(int1);
                        float float1 = (float)worldSound0.radius * float0;

                        for (double double0 = 0.0; double0 < Math.PI * 2; double0 += Math.PI / 20) {
                            this.DrawIsoLine(
                                (float)worldSound0.x + float1 * (float)Math.cos(double0),
                                (float)worldSound0.y + float1 * (float)Math.sin(double0),
                                (float)worldSound0.x + float1 * (float)Math.cos(double0 + (Math.PI / 20)),
                                (float)worldSound0.y + float1 * (float)Math.sin(double0 + (Math.PI / 20)),
                                (float)worldSound0.z,
                                1.0F,
                                1.0F,
                                1.0F,
                                1.0F,
                                1
                            );
                        }
                    }

                    if (!GameServer.bServer) {
                        IsoChunkMap isoChunkMap = IsoWorld.instance.CurrentCell.getChunkMap(0);
                        if (isoChunkMap != null && !isoChunkMap.ignore) {
                            for (int int2 = 0; int2 < IsoChunkMap.ChunkGridWidth; int2++) {
                                for (int int3 = 0; int3 < IsoChunkMap.ChunkGridWidth; int3++) {
                                    IsoChunk isoChunk = isoChunkMap.getChunk(int3, int2);
                                    if (isoChunk != null) {
                                        for (int int4 = 0; int4 < isoChunk.SoundList.size(); int4++) {
                                            zombie.WorldSoundManager.WorldSound worldSound1 = (zombie.WorldSoundManager.WorldSound)isoChunk.SoundList.get(int4);
                                            float float2 = (float)worldSound1.radius * float0;

                                            for (double double1 = 0.0; double1 < Math.PI * 2; double1 += Math.PI / 20) {
                                                this.DrawIsoLine(
                                                    (float)worldSound1.x + float2 * (float)Math.cos(double1),
                                                    (float)worldSound1.y + float2 * (float)Math.sin(double1),
                                                    (float)worldSound1.x + float2 * (float)Math.cos(double1 + (Math.PI / 20)),
                                                    (float)worldSound1.y + float2 * (float)Math.sin(double1 + (Math.PI / 20)),
                                                    (float)worldSound1.z,
                                                    0.0F,
                                                    1.0F,
                                                    1.0F,
                                                    1.0F,
                                                    1
                                                );
                                                float float3 = (float)(isoChunk.wx * 10) + 0.1F;
                                                float float4 = (float)(isoChunk.wy * 10) + 0.1F;
                                                float float5 = (float)((isoChunk.wx + 1) * 10) - 0.1F;
                                                float float6 = (float)((isoChunk.wy + 1) * 10) - 0.1F;
                                                this.DrawIsoLine(float3, float4, float5, float4, (float)worldSound1.z, 0.0F, 1.0F, 1.0F, 1.0F, 1);
                                                this.DrawIsoLine(float5, float4, float5, float6, (float)worldSound1.z, 0.0F, 1.0F, 1.0F, 1.0F, 1);
                                                this.DrawIsoLine(float5, float6, float3, float6, (float)worldSound1.z, 0.0F, 1.0F, 1.0F, 1.0F, 1);
                                                this.DrawIsoLine(float3, float6, float3, float4, (float)worldSound1.z, 0.0F, 1.0F, 1.0F, 1.0F, 1);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    private void DrawIsoLine(
        float float1, float float2, float float6, float float7, float float3, float float9, float float10, float float11, float float12, int _int
    ) {
        float float0 = IsoUtils.XToScreenExact(float1, float2, float3, 0);
        float float4 = IsoUtils.YToScreenExact(float1, float2, float3, 0);
        float float5 = IsoUtils.XToScreenExact(float6, float7, float3, 0);
        float float8 = IsoUtils.YToScreenExact(float6, float7, float3, 0);
        LineDrawer.drawLine(float0, float4, float5, float8, float9, float10, float11, float12, _int);
    }

    public float getHearingMultiplier(IsoZombie isoZombie) {
        return isoZombie == null ? this.getHearingMultiplier(2) : this.getHearingMultiplier(isoZombie.hearing);
    }

    public float getHearingMultiplier(int _int) {
        if (_int == 1) {
            return 3.0F;
        } else {
            return _int == 3 ? 0.45F : 1.0F;
        }
    }

    public static final class ResultBiggestSound {
        public zombie.WorldSoundManager.WorldSound sound;
        public float attract;

        public zombie.WorldSoundManager.ResultBiggestSound init(zombie.WorldSoundManager.WorldSound _sound, float _attract) {
            this.sound = _sound;
            this.attract = _attract;
            return this;
        }
    }

    public class WorldSound {
        public Object source = null;
        public int life = 1;
        public int radius;
        public boolean stresshumans;
        public int volume;
        public int x;
        public int y;
        public int z;
        public float zombieIgnoreDist = 0.0F;
        public boolean sourceIsZombie;
        public float stressMod = 1.0F;
        public boolean bRepeating;

        public zombie.WorldSoundManager.WorldSound init(Object object, int int0, int int1, int int2, int int3, int int4) {
            return this.init(object, int0, int1, int2, int3, int4, false, 0.0F, 1.0F);
        }

        public zombie.WorldSoundManager.WorldSound init(Object object, int int0, int int1, int int2, int int3, int int4, boolean _boolean) {
            return this.init(object, int0, int1, int2, int3, int4, _boolean, 0.0F, 1.0F);
        }

        public zombie.WorldSoundManager.WorldSound init(
            Object object, int int0, int int1, int int2, int int3, int int4, boolean _boolean, float float0, float float1
        ) {
            this.source = object;
            this.life = 1;
            this.x = int0;
            this.y = int1;
            this.z = int2;
            this.radius = int3;
            this.volume = int4;
            this.stresshumans = _boolean;
            this.zombieIgnoreDist = float0;
            this.stressMod = float1;
            this.sourceIsZombie = object instanceof IsoZombie;
            this.bRepeating = false;
            LuaEventManager.triggerEvent("OnWorldSound", int0, int1, int2, int3, int4, object);
            return this;
        }

        public zombie.WorldSoundManager.WorldSound init(
            boolean boolean1, int int0, int int1, int int2, int int3, int int4, boolean boolean0, float float0, float float1
        ) {
            zombie.WorldSoundManager.WorldSound worldSound0 = this.init(null, int0, int1, int2, int3, int4, boolean0, float0, float1);
            worldSound0.sourceIsZombie = boolean1;
            return worldSound0;
        }
    }
}
